#pragma once

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<queue>
#include<semaphore.h>

class QueueSafeSem{
  public:
  QueueSafeSem(){
    capacity =2;
    sem_init(&lock_,0,2);

    sem_init(&cons_sem,0,0);
    sem_init(&prod_sem,0,capacity);
  }
  ~QueueSafeSem(){
    sem_destroy(&lock_);
    sem_destroy(&cons_sem);
    sem_destroy(&prod_sem);
  }

  void Push(int data){
    sem_wait(&prod_sem);
    sem_wait(&lock_);
    que_.push(data);
    printf("i am product %d\n",data);
    sem_post(&lock_);
    sem_post(&cons_sem);

  }
  int  Pop(){
    sem_wait(&cons_sem);
  sem_wait(&lock_);
  int tmp=que_.front();
  que_.pop();
    printf("i am consume %d\n",tmp);
    sem_post(&lock_);
    sem_post(&prod_sem);
    return tmp;
  }
  private:
  std::queue<int> que_;

  size_t capacity;  
  sem_t lock_;

  sem_t cons_sem;
  sem_t prod_sem;
};
